<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 内部就业经历模型
 * 管理员工在公司内部的经历（调动、培训、奖惩等）
 */
class InternalExperience extends Model
{
    use HasFactory;

    /**
     * 表名
     */
    protected $table = 'internal_experiences';

    /**
     * 可填充字段
     */
    protected $fillable = [
        'employee_id',
        'experience_type',
        'title',
        'description',
        'start_date',
        'end_date',
        'is_current',
        'department_id',
        'department_name',
        'position_id',
        'position_name',
        'position_level',
        'content',
        'training_type',
        'training_provider',
        'training_hours',
        'training_result',
        'project_name',
        'project_role',
        'project_responsibilities',
        'project_result',
        'reward_type',
        'punishment_type',
        'reward_amount',
        'reward_reason',
        'punishment_reason',
        'from_department_id',
        'from_department_name',
        'to_department_id',
        'to_department_name',
        'transfer_reason',
        'transfer_type',
        'approved_by',
        'approved_at',
        'approval_notes',
        'attachments',
        'is_active',
        'sort_order',
    ];

    /**
     * 字段类型转换
     */
    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'approved_at' => 'date',
        'is_current' => 'boolean',
        'is_active' => 'boolean',
        'training_hours' => 'decimal:2',
        'reward_amount' => 'decimal:2',
        'attachments' => 'array',
    ];

    /**
     * 日期字段
     */
    protected $dates = [
        'start_date',
        'end_date',
        'approved_at',
        'created_at',
        'updated_at',
    ];

    // ============ 常量定义 ============

    public const TYPE_TRANSFER = 'transfer';
    public const TYPE_PROJECT = 'project';
    public const TYPE_TRAINING = 'training';
    public const TYPE_AWARD = 'award';
    public const TYPE_PUNISHMENT = 'punishment';

    public const TRAINING_PASSED = 'passed';
    public const TRAINING_FAILED = 'failed';

    public const PROJECT_SUCCESS = 'success';
    public const PROJECT_FAILURE = 'failure';
    public const PROJECT_ONGOING = 'ongoing';

    public const TRANSFER_PROMOTION = 'promotion';
    public const TRANSFER_DEMOTION = 'demotion';
    public const TRANSFER_TRANSFER = 'transfer';

    // ============ 关联关系 ============

    /**
     * 关联员工
     */
    public function employee(): BelongsTo
    {
        return $this->belongsTo(Employee::class);
    }

    // ============ 访问器 ============

    /**
     * 获取经历类型标签
     */
    public function getExperienceTypeLabelAttribute(): string
    {
        return match($this->experience_type) {
            self::TYPE_TRANSFER => '调动',
            self::TYPE_PROJECT => '项目',
            self::TYPE_TRAINING => '培训',
            self::TYPE_AWARD => '奖励',
            self::TYPE_PUNISHMENT => '处罚',
            default => $this->experience_type ?? '未知'
        };
    }

    /**
     * 获取培训结果标签
     */
    public function getTrainingResultLabelAttribute(): string
    {
        return match($this->training_result) {
            self::TRAINING_PASSED => '合格',
            self::TRAINING_FAILED => '不合格',
            default => $this->training_result ?? '未知'
        };
    }

    /**
     * 获取项目结果标签
     */
    public function getProjectResultLabelAttribute(): string
    {
        return match($this->project_result) {
            self::PROJECT_SUCCESS => '成功',
            self::PROJECT_FAILURE => '失败',
            self::PROJECT_ONGOING => '进行中',
            default => $this->project_result ?? '未知'
        };
    }

    /**
     * 获取调动类型标签
     */
    public function getTransferTypeLabelAttribute(): string
    {
        return match($this->transfer_type) {
            self::TRANSFER_PROMOTION => '晋升',
            self::TRANSFER_DEMOTION => '降职',
            self::TRANSFER_TRANSFER => '调动',
            default => $this->transfer_type ?? '未知'
        };
    }

    /**
     * 获取经历时长
     */
    public function getDurationAttribute(): ?string
    {
        if (!$this->start_date) {
            return null;
        }

        $endDate = $this->end_date ?: now();
        $months = $this->start_date->diffInMonths($endDate);

        if ($months < 12) {
            return $months . '个月';
        }

        $years = floor($months / 12);
        $remainingMonths = $months % 12;

        $duration = $years . '年';
        if ($remainingMonths > 0) {
            $duration .= $remainingMonths . '个月';
        }

        return $duration;
    }

    /**
     * 获取部门信息
     */
    public function getDepartmentInfoAttribute(): string
    {
        if ($this->department_name) {
            return $this->department_name;
        }

        return '未分配部门';
    }

    /**
     * 获取职位信息
     */
    public function getPositionInfoAttribute(): string
    {
        $info = $this->position_name ?? '未知职位';

        if ($this->position_level) {
            $info .= " ({$this->position_level})";
        }

        return $info;
    }

    /**
     * 获取调动信息
     */
    public function getTransferInfoAttribute(): string
    {
        if ($this->experience_type !== self::TYPE_TRANSFER) {
            return '';
        }

        $info = '';

        if ($this->from_department_name) {
            $info .= "从 {$this->from_department_name} ";
        }

        if ($this->to_department_name) {
            $info .= "调至 {$this->to_department_name}";
        }

        if ($this->transfer_reason) {
            $info .= " (原因: {$this->transfer_reason})";
        }

        return $info ?: '部门调动';
    }

    // ============ 作用域 ============

    /**
     * 当前经历作用域
     */
    public function scopeCurrent($query)
    {
        return $query->where('is_current', true);
    }

    /**
     * 历史经历作用域
     */
    public function scopeHistorical($query)
    {
        return $query->where('is_current', false);
    }

    /**
     * 按类型筛选作用域
     */
    public function scopeByType($query, $type)
    {
        return $query->where('experience_type', $type);
    }

    /**
     * 按部门筛选作用域
     */
    public function scopeByDepartment($query, $departmentId)
    {
        return $query->where('department_id', $departmentId);
    }

    /**
     * 按职位筛选作用域
     */
    public function scopeByPosition($query, $positionId)
    {
        return $query->where('position_id', $positionId);
    }

    /**
     * 按时间范围筛选作用域
     */
    public function scopeByDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('start_date', [$startDate, $endDate]);
    }

    /**
     * 已批准作用域
     */
    public function scopeApproved($query)
    {
        return $query->whereNotNull('approved_at');
    }

    /**
     * 未批准作用域
     */
    public function scopeNotApproved($query)
    {
        return $query->whereNull('approved_at');
    }

    // ============ 业务方法 ============

    /**
     * 批准经历
     */
    public function approve(string $approvedBy, ?string $notes = null): bool
    {
        $this->approved_by = $approvedBy;
        $this->approved_at = now();
        $this->approval_notes = $notes;

        return $this->save();
    }

    /**
     * 结束当前经历
     */
    public function end(\DateTime $endDate): bool
    {
        $this->end_date = $endDate;
        $this->is_current = false;

        return $this->save();
    }

    /**
     * 设置为当前经历
     */
    public function setAsCurrent(): bool
    {
        $this->is_current = true;
        $this->end_date = null;

        return $this->save();
    }

    /**
     * 添加附件
     */
    public function addAttachment(array $attachment): bool
    {
        $attachments = $this->attachments ?? [];
        $attachments[] = $attachment;

        $this->attachments = $attachments;
        return $this->save();
    }

    /**
     * 移除附件
     */
    public function removeAttachment(string $attachmentId): bool
    {
        $attachments = $this->attachments ?? [];
        $attachments = array_filter($attachments, fn($attachment) => $attachment['id'] !== $attachmentId);

        $this->attachments = array_values($attachments);
        return $this->save();
    }

    // ============ 静态方法 ============

    /**
     * 创建调动记录
     */
    public static function createTransfer(
        int $employeeId,
        array $transferData
    ): self {
        return self::create(array_merge($transferData, [
            'employee_id' => $employeeId,
            'experience_type' => self::TYPE_TRANSFER,
            'title' => '部门调动',
        ]));
    }

    /**
     * 创建培训记录
     */
    public static function createTraining(
        int $employeeId,
        array $trainingData
    ): self {
        return self::create(array_merge($trainingData, [
            'employee_id' => $employeeId,
            'experience_type' => self::TYPE_TRAINING,
            'title' => $trainingData['training_type'] ?? '培训',
        ]));
    }

    /**
     * 创建项目记录
     */
    public static function createProject(
        int $employeeId,
        array $projectData
    ): self {
        return self::create(array_merge($projectData, [
            'employee_id' => $employeeId,
            'experience_type' => self::TYPE_PROJECT,
            'title' => $projectData['project_name'] ?? '项目经历',
        ]));
    }

    /**
     * 创建奖励记录
     */
    public static function createAward(
        int $employeeId,
        array $awardData
    ): self {
        return self::create(array_merge($awardData, [
            'employee_id' => $employeeId,
            'experience_type' => self::TYPE_AWARD,
            'title' => '奖励',
        ]));
    }

    /**
     * 创建处罚记录
     */
    public static function createPunishment(
        int $employeeId,
        array $punishmentData
    ): self {
        return self::create(array_merge($punishmentData, [
            'employee_id' => $employeeId,
            'experience_type' => self::TYPE_PUNISHMENT,
            'title' => '处罚',
        ]));
    }

    /**
     * 验证经历数据
     */
    public static function validateExperienceData(array $data): array
    {
        $errors = [];

        // 必填字段验证
        $requiredFields = ['employee_id', 'experience_type', 'title', 'start_date'];
        foreach ($requiredFields as $field) {
            if (empty($data[$field])) {
                $errors[] = "{$field} 字段不能为空";
            }
        }

        // 经历类型验证
        $validTypes = [self::TYPE_TRANSFER, self::TYPE_PROJECT, self::TYPE_TRAINING, self::TYPE_AWARD, self::TYPE_PUNISHMENT];
        if (!empty($data['experience_type']) && !in_array($data['experience_type'], $validTypes)) {
            $errors[] = "无效的经历类型";
        }

        // 时间验证
        if (!empty($data['start_date']) && !empty($data['end_date'])) {
            $startDate = strtotime($data['start_date']);
            $endDate = strtotime($data['end_date']);

            if ($startDate && $endDate && $startDate >= $endDate) {
                $errors[] = "结束时间必须晚于开始时间";
            }
        }

        // 培训时长验证
        if (!empty($data['training_hours']) && (!is_numeric($data['training_hours']) || $data['training_hours'] <= 0)) {
            $errors[] = "培训学时必须是有效的正数";
        }

        // 奖励金额验证
        if (!empty($data['reward_amount']) && (!is_numeric($data['reward_amount']) || $data['reward_amount'] < 0)) {
            $errors[] = "奖励金额必须是有效的数字";
        }

        return $errors;
    }
}
